文章目录
  1. 1. Vertor的1倍扩容
  2. 2. 线程安全
  3. 3. 总结
  4. 4. 参考

VectorJava编程中最常用的容器类之一,它是基于动态的数组实现的,在面试时常常被与ArrayList作比较!

       看过源码的小伙伴可能有相同的感觉:进入Vector.Java会顿一会儿,还以为自己点错进去ArrayList的源码文件了呢!是的,VectorArrayList的实现基本相似,同样是基于动态数组,同样是需要扩容,本文在接下来的源码分析中与ArraryList重复的部分不再累赘,如需要了解的同学请点入进ArrarList源码分析

Vertor的1倍扩容

还记得ArrayList每次扩容为元数组的0.5倍不?Vector在进行扩容操作时与ArrayList略微不同

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/**
* The amount by which the capacity of the vector is automatically
* incremented when its size becomes greater than its capacity. If
* the capacity increment is less than or equal to zero, the capacity
* of the vector is doubled each time it needs to grow.
*
* @serial
*/

protected int capacityIncrement;//用于指定每次扩容的容量

private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
capacityIncrement : oldCapacity);//如不指定capacityIncrement,默认扩容的容量为原数组的容量
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
elementData = Arrays.copyOf(elementData, newCapacity);
}

       细心的小伙伴可以发现Vector中多了一个capacityIncrement变量,该变量是用于指定每次扩容的增量,如果不指定该变量,在grow中可以发现Vector默认就扩容为原数组的1倍

线程安全

Vertor是线程安全的

       Vertor源码中另一个比较显眼的地方就是绝大部分方法都有synchronized关键字,大家都知道这个关键字是用于线程同步的,所以Vector类是线程安全的!
但是即使它所有的方法都被修饰成同步,也不意味着调用它的时候永远都不需要同步手段了:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
private static Vector<Integer> vector=new Vector<Integer>();
public static void main(String[] args) {
while(true)
{
for(int i=0;i<10;i++)
{
vector.add(i);
}

Thread removeThread=new Thread(new Runnable(){
@Override
public void run()
{

for(int i=0;i<vector.size();i++)
{
vector.remove(i);
}
}
});

Thread printThread=new Thread(new Runnable(){
@Override
public void run()
{

for(int i=0;i<vector.size();i++)
{
System.out.println(vector.get(i));
}
}
});

removeThread.start();
printThread.start();

while(Thread.activeCount()>20);

}
}

       大家运行此段代码时 跑了一小段时间之后会发现有ArrayIndexOutOfBoundsException异常,这里Vector的get,remove,size方法尽管有synchronized修饰,但是在多线程环境中,如果不在方法端额外做同步措施的话,这段代码仍然是不安全的,如果一个线程删除了序号i的元素之后,另一个线程去访问这个i的话就直接回抛异常,所以保证这段代码安全还需要再run里面再添加
synchronized修饰

总结

  1. Vector的实现与ArrayList基本一致
  2. Vector在扩容时可以指定每次扩容的增长,如果不指定则默认增加1倍
  3. Vector是线程安全的,但是在多线程环境下可能还是需要用synchronized关键词才能保证真正的安全

参考

  • 《深入理解Java虚拟机》.周志明,第十三章,Page388-389

本作品采用[知识共享署名-非商业性使用-相同方式共享 2.5]中国大陆许可协议进行许可,我的博客欢迎复制共享,但在同时,希望保留我的署名权kubiCode,并且,不得用于商业用途。如您有任何疑问或者授权方面的协商,请给我留言

文章目录
  1. 1. Vertor的1倍扩容
  2. 2. 线程安全
  3. 3. 总结
  4. 4. 参考